package edu.hubu.authentication;

import edu.hubu.model.Token;
import edu.hubu.service.impl.TokenService;
import edu.hubu.service.impl.UserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * @author moonlan
 * @date 2020/9/27 18:32
 */

public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    private static final Logger log = org.slf4j.LoggerFactory.getLogger(JwtAuthenticationFilter.class);
    private final UserDetailsService userDetailsService;
    private final UserService usersService;
    private final TokenService tokenService;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager, UserDetailsService userDetailsService, UserService userService, TokenService tokenService) {
        super(authenticationManager);
        this.userDetailsService = userDetailsService;
        this.usersService = userService;
        this.tokenService = tokenService;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        String token = request.getHeader("token");

        //判断是否有token
        if (token == null || !token.startsWith("Bearer ")) {
            chain.doFilter(request, response);
            return;
        }

        UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(token, response);

        if (authenticationToken != null) {
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);

            //放行
            chain.doFilter(request, response);
            return;
        }

        throw new AccessDeniedException("认证失败");

    }

    private UsernamePasswordAuthenticationToken getAuthentication(String token, HttpServletResponse response) throws AuthenticationException {


        Claims claims = Jwts.parser().setSigningKey("oLmRgosdSxz3XOlptCUUvytajh7ybxc1P4c8fBlQMEExr73HSu0olNOA4khWdRm2").parseClaimsJws(token.replace("Bearer ", "")).getBody();

        //得到用户名
        String userId = claims.getSubject();
        //得到数据库的token
//        User one = usersService.findEntityById(userId);
        //        List<Token> tokens = one.getTokens();
        Token byUserId = tokenService.findByUserId(userId);
        Date expiration = claims.getExpiration();

        //判断是否过期
        Date now = new Date();
        String userToken = byUserId.getTokenToken();
        if (now.getTime() <= expiration.getTime() && !byUserId.isTokenIsDeleted() && !byUserId.isTokenIsForbidden() && userToken != null && !userToken.isEmpty() && userToken.equals(token.replace("Bearer ", ""))) {
            UserDetails user = userDetailsService.loadUserByUsername(userId);
            log.info(userId + "正在尝试做些什么");
            return new UsernamePasswordAuthenticationToken(userId, user.getPassword(), user.getAuthorities());
        }
        log.error(userId + "尝试做些什么，但是失败了");
        return null;
    }
}
